<?php

namespace App\Request\auth\Service\Utils;

use App\Enum\Wechat\SendSubscribeTemplate;
use App\Exception\BusinessException;
use App\Utils\WeChatTemplateHelper;
use EasyWeChat\MiniApp\Application;
use Exception;
use Hyperf\Context\ApplicationContext;
use Hyperf\Filesystem\FilesystemFactory;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Throwable;
use function Hyperf\Config\config;
use function Hyperf\Support\env;

/**
 * 微信小程序服务类
 */
class WeChatService
{

    // 小程序首页页面
    const PAGE = 'pages/index/index';

    protected Application $app;

    public function __construct()
    {
        $this->app = new Application([
            'app_id' => 'wx437a8c17cdf890e3',
            'secret' => 'cc2c38427f2b4c7ef0853fcf6c442507',
            'token' => env('EASYWECHAT_TOEKN', 'FGHrwiMra44ErttCXgJc2iDtF2oLLpPJ'),
            'use_stable_access_token' => true,

            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'permission' => 0777,
                'file' => BASE_PATH . '/runtime/logs/wechat.log',
            ],
        ]);

    }

    /**
     * 微信小程序授权
     * @param string $code 授权码
     * @return array
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     * @throws Exception
     */
    public function authorize(string $code): array
    {
        $utils = $this->app->getUtils();
        try {
            $response = $utils->codeToSession($code);
            return [
                'openid' => $response['openid'],
                "nickName" => "微信小程序用户",
                "avatar" => "/static/images/avatar.jpg",
            ];
        } catch (Exception $exception) {
            throw new BusinessException($exception->getMessage());
        }
    }

    /**
     * 微信小程序授权手机号
     * @param string $code 授权码
     * @return array
     * @throws ClientExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws Exception
     */
    public function authorizePhone(string $code): array
    {
        $api = $this->app->getClient();
        try {
            $res = $api->postJson('/wxa/business/getuserphonenumber', ['code' => $code,])->toArray();
            if ($res['errcode'] > 0) {
                throw new BusinessException('获取手机号失败：' . json_encode($res));
            }
            return $res['phone_info'];
        } catch (Throwable $exception) {
            throw new BusinessException($exception->getMessage());
        }
    }


    /**
     * 生成小程序码
     * @param string $scene 小程序码场景
     * @return string
     * @throws Exception
     */
    public function generateQrCode(string $scene): string
    {
        $api = $this->app->getClient();
        try {
            $res = $api->postJson('/wxa/getwxacodeunlimit', [
                'scene' => $scene,
                'page' => self::PAGE,
                'check_path' => false,
            ]);
            $day = date('Ymd');
            $path = "/qrcode/{$day}";
            $fileName = "/{$scene}.png";
            $filePath = config('app_url') . $path . $fileName;
            $filesystemFactory = ApplicationContext::getContainer()->get(FilesystemFactory::class);
            $filesystem = $filesystemFactory->get('local');
            if (!$filesystem->directoryExists($path)) {
                $filesystem->createDirectory($path);
            }
            $res->toStream();
            $res->saveAs("storage" . $path . $fileName);
            //设置文件权限
            $fullDir = BASE_PATH . "/storage" . $path;
            var_dump($fullDir);
            if(is_dir($fullDir)){
                chmod($fullDir, 0777);
            }
            return $filePath;
        } catch (Throwable $exception) {
            throw new BusinessException("小程序二维码生成失败：" . $exception->getMessage());
        }
    }

    /**
     * 小程序发送订阅消息
     * @throws Exception
     */
    public function sendSubscriptionMessage(SendSubscribeTemplate $templateId, array $data, string $openid): void
    {
        $api = $this->app->getClient();
        try {
            $res = $api->postJson('/cgi-bin/message/subscribe/send', [
                'template_id' => $templateId,
                'page' => self::PAGE,
                'touser' => $openid,
                'data' => WeChatTemplateHelper::getTemplateData($templateId, $data),
            ])->toArray();
            if ($res['errcode'] > 0) {
                throw new BusinessException(json_encode($res));
            }
        } catch (Throwable $exception) {
            throw new BusinessException("发送订阅消息失败：" . $exception->getMessage());
        }
    }


}